﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TrabajoPractico1
{
    public class ArbolesBusquedas
    {

#region Declaración de variables

        //Cantidad de nodos visitados
        int nodosAnchura = 0, nodosProfundidad = 0;

        //Estas listas van a guardar los nodos visitados
        ArrayList listaNodosVisitadosAn = new ArrayList();
        ArrayList listaNodosVisitadosPr = new ArrayList();

        //Creo raíz
        NodoArbol raiz = new NodoArbol("Bruno", "Nodo Raíz");

        // Nodos del primer nivel
        NodoArbol nivel1hijo0 = new NodoArbol("Renato", "Bruno");
        NodoArbol nivel1hijo1 = new NodoArbol("Beatriz", "Bruno");
        NodoArbol nivel1hijo2 = new NodoArbol("Ramón", "Bruno");

        //Nodos del segundo nivel
        NodoArbol nivel2hijo0 = new NodoArbol("Rodolfo", "Renato");
        NodoArbol nivel2hijo1 = new NodoArbol("Gabriel", "Renato");
        NodoArbol nivel2hijo2 = new NodoArbol("Norma", "Beatriz");
        NodoArbol nivel2hijo3 = new NodoArbol("Javier", "Beatriz");
        NodoArbol nivel2hijo4 = new NodoArbol("José", "Beatriz");
        NodoArbol nivel2hijo5 = new NodoArbol("Irma", "Ramón");
        NodoArbol nivel2hijo6 = new NodoArbol("Claudia", "Ramón");

        //Nodos del tercer nivel
        NodoArbol nivel3hijo0 = new NodoArbol("Facundo", "Rodolfo");
        NodoArbol nivel3hijo1 = new NodoArbol("Luciano", "Rodolfo");
        NodoArbol nivel3hijo2 = new NodoArbol("Agustina", "Rodolfo");
        NodoArbol nivel3hijo3 = new NodoArbol("Lucía", "Norma");
        NodoArbol nivel3hijo4 = new NodoArbol("Sofía", "Norma");
        NodoArbol nivel3hijo5 = new NodoArbol("Mara", "Javier");
        NodoArbol nivel3hijo6 = new NodoArbol("Bautista", "Javier");
        NodoArbol nivel3hijo7 = new NodoArbol("Joaquín", "José");
        NodoArbol nivel3hijo8 = new NodoArbol("Estéfano", "José");
        NodoArbol nivel3hijo9 = new NodoArbol("Melisa", "José");
        NodoArbol nivel3hijo10 = new NodoArbol("Juan", "Irma");
        NodoArbol nivel3hijo11 = new NodoArbol("Carolina", "Irma");

        //Nodos del cuarto nivel
        NodoArbol nivel4hijo0 = new NodoArbol("Micaela", "Lucía");
        NodoArbol nivel4hijo1 = new NodoArbol("Germán", "Lucía");
        NodoArbol nivel4hijo2 = new NodoArbol("Lautaro", "Juan");

#endregion

#region Constructor 

        //Constructor de la clase

        public ArbolesBusquedas()
        {
            this.crearArbol(raiz);
            this.segundoNivelArbol(nivel1hijo0, nivel1hijo1, nivel1hijo2);
            this.tercerNivelArbol(nivel2hijo0, nivel2hijo2, nivel2hijo3, nivel2hijo4, nivel2hijo5);
            this.cuartoNivelArbol(nivel3hijo3, nivel3hijo10);

        }
#endregion

#region Métodos 

        // Construyo el primer nivel del árbol
        public void crearArbol(NodoArbol raiz)
        {
            raiz.addHijo(nivel1hijo0);
            raiz.addHijo(nivel1hijo1);
            raiz.addHijo(nivel1hijo2);
        }

        //Construyo el segundo nivel del árbol
        public void segundoNivelArbol(NodoArbol nivel1hijo0, NodoArbol nivel1hijo1, NodoArbol nivel1hijo2)
        {
            nivel1hijo0.addHijo(nivel2hijo0);
            nivel1hijo0.addHijo(nivel2hijo1);
            nivel1hijo1.addHijo(nivel2hijo2);
            nivel1hijo1.addHijo(nivel2hijo3);
            nivel1hijo1.addHijo(nivel2hijo4);
            nivel1hijo2.addHijo(nivel2hijo5);
            nivel1hijo2.addHijo(nivel2hijo6);

        }

        //Construyo el tercer nivel del árbol
        public void tercerNivelArbol(NodoArbol nivel2hijo0, NodoArbol nivel2hijo2, NodoArbol nivel2hijo3, NodoArbol nivel2hijo4, NodoArbol nivel2hijo5)
        {
            nivel2hijo0.addHijo(nivel3hijo0);
            nivel2hijo0.addHijo(nivel3hijo1);
            nivel2hijo0.addHijo(nivel3hijo2);
            nivel2hijo2.addHijo(nivel3hijo3);
            nivel2hijo2.addHijo(nivel3hijo4);
            nivel2hijo3.addHijo(nivel3hijo5);
            nivel2hijo3.addHijo(nivel3hijo6);
            nivel2hijo4.addHijo(nivel3hijo7);
            nivel2hijo4.addHijo(nivel3hijo8);
            nivel2hijo4.addHijo(nivel3hijo9);
            nivel2hijo5.addHijo(nivel3hijo10);
            nivel2hijo5.addHijo(nivel3hijo11);

        }

        //Construyo el cuarto nivel del árbol
        public void cuartoNivelArbol(NodoArbol nivel3hijo3, NodoArbol nivel3hijo10)
        {
            nivel3hijo3.addHijo(nivel4hijo0);
            nivel3hijo3.addHijo(nivel4hijo1);
            nivel3hijo10.addHijo(nivel4hijo2);

        }

        //Método que devuelve el nodo del árbol correspondiente al string ingresado por teclado, realizada la búsqueda Primero en Anchura
        public NodoArbol busquedaAnchura(string c)
        {
            Queue<NodoArbol> colaAuxiliar = new Queue<NodoArbol>();
            colaAuxiliar.Enqueue(raiz);


            while (colaAuxiliar.Count != 0)
            {
                NodoArbol cabeza = colaAuxiliar.Dequeue();
                listaNodosVisitadosAn.Add(cabeza.getElemento());
                {
                    nodosAnchura++;
                }

                if (cabeza.getElemento() == c)
                {
                    return cabeza;
                }

                else

                    foreach (NodoArbol hijo in cabeza.getHijos())
                    {
                        colaAuxiliar.Enqueue(hijo);

                    }

            }
            return null;

        }

        //Método que devuelve el nodo del árbol correspondiente al string ingresado por teclado, realizada la búsqueda Primero en Profundidad
        public NodoArbol busquedaProfundidad(string c)
        {
            List<NodoArbol> listahijos = new List<NodoArbol>();

            Stack<NodoArbol> pilaAuxiliar = new Stack<NodoArbol>();
            pilaAuxiliar.Push(raiz);

            while (pilaAuxiliar.Count != 0)
            {
                NodoArbol cabeza = pilaAuxiliar.Pop();
                listaNodosVisitadosPr.Add(cabeza.getElemento());
                if (cabeza.getElemento() == c)
                    return cabeza;
                else
                    listahijos = cabeza.getHijos();

                for (int i = cabeza.getHijos().Count - 1; i >= 0; i--)
                {
                    pilaAuxiliar.Push(listahijos[i]);

                }
            }
            return null;
        }


        //Devuelve la cantidad de nodos recorridos para encontrar la solución: 1-Búsqueda en Anchura 2-Búsqueda en Profundidad
        public int cantNodosVisitados(int tipo)
        {
            if (tipo == 1)
            {
                nodosAnchura = listaNodosVisitadosAn.Count;
                return nodosAnchura;
            }
            else
            {
                if (tipo == 2)
                {
                    nodosProfundidad = listaNodosVisitadosPr.Count;
                    return nodosProfundidad;
                }
                else
                {
                    return 0;
                }
            }
        }

        //Devuelve los nodos recorridos para encontrar la solución: 1-Búsqueda en Anchura 2-Búsqueda en Profundidad
        public ArrayList nodosVisitados(int tipo)
        {
            if (tipo == 1)
            {
                return listaNodosVisitadosAn;
            }
            else
            {

                if (tipo == 2)
                {
                    return listaNodosVisitadosPr;
                }
                else
                {
                    return null;
                }
            }


        }


    }
}

#endregion